package api

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
	"time"

	"github.com/babytap/server/internal/database"
	"github.com/babytap/server/internal/models"
	"github.com/gofiber/fiber/v2"
)

// CardHandler 卡片处理器
type CardHandler struct {
	repo *database.CardRepository
	// UDP 发现服务引用
	udpDiscovery interface{}
}

// NewCardHandler 创建新的卡片处理器
func NewCardHandler(repo *database.CardRepository) *CardHandler {
	return &CardHandler{repo: repo}
}

// NewCardHandlerWithUDPDiscovery 创建新的卡片处理器（带UDP发现服务）
func NewCardHandlerWithUDPDiscovery(repo *database.CardRepository, udpDiscovery interface{}) *CardHandler {
	return &CardHandler{
		repo:         repo,
		udpDiscovery: udpDiscovery,
	}
}

// RegisterRoutes 注册路由
func (h *CardHandler) RegisterRoutes(app *fiber.App) {
	api := app.Group("/api")
	{
		api.Get("/cards", h.GetCards)
		api.Get("/cards/:id", h.GetCard)
		api.Post("/cards", h.CreateCard)
		api.Put("/cards/:id", h.UpdateCard)
		api.Delete("/cards/:id", h.DeleteCard)
		api.Get("/images/*", h.GetImage)
		api.Get("/audio/*", h.GetAudio)
		api.Get("/sync", h.GetSyncStatus)

		// 新增的 GORM 功能端点
		api.Get("/cards/search", h.SearchCards)
		api.Get("/cards/date-range", h.GetCardsByDateRange)
		api.Post("/cards/batch", h.BatchCreateCards)

		// UDP 广播端点
		api.Post("/broadcast", h.SendUDPBroadcast)

		// 设备名称管理端点
		api.Get("/device/name", h.GetDeviceName)
		api.Put("/device/name", h.SetDeviceName)
	}

	// 健康检查
	app.Get("/health", h.HealthCheck)
}

// GetCards 获取所有卡片
func (h *CardHandler) GetCards(c *fiber.Ctx) error {
	cards, err := h.repo.GetAllCards()
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取卡片列表失败",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: cards,
	})
}

// GetCard 获取单个卡片
func (h *CardHandler) GetCard(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "无效的卡片ID",
		})
	}

	card, err := h.repo.GetCardByID(id)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取卡片失败",
		})
	}

	if card == nil {
		return c.Status(fiber.StatusNotFound).JSON(models.APIResponse{
			Code: 404,
			Data: "卡片不存在",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: card,
	})
}

// CreateCard 创建卡片
func (h *CardHandler) CreateCard(c *fiber.Ctx) error {
	var req models.CreateCardRequest
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "请求参数无效",
		})
	}

	card, err := h.repo.CreateCard(&req)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "创建卡片失败",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: card,
	})
}

// UpdateCard 更新卡片
func (h *CardHandler) UpdateCard(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "无效的卡片ID",
		})
	}

	var req models.UpdateCardRequest
	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "请求参数无效",
		})
	}

	card, err := h.repo.UpdateCard(id, &req)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "更新卡片失败",
		})
	}

	if card == nil {
		return c.Status(fiber.StatusNotFound).JSON(models.APIResponse{
			Code: 404,
			Data: "卡片不存在",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: card,
	})
}

// DeleteCard 删除卡片
func (h *CardHandler) DeleteCard(c *fiber.Ctx) error {
	idStr := c.Params("id")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "无效的卡片ID",
		})
	}

	success, err := h.repo.DeleteCard(id)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "删除卡片失败",
		})
	}

	if !success {
		return c.Status(fiber.StatusNotFound).JSON(models.APIResponse{
			Code: 404,
			Data: "卡片不存在",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: map[string]string{"message": "卡片删除成功"},
	})
}

// GetImage 获取图片文件
func (h *CardHandler) GetImage(c *fiber.Ctx) error {
	imagePath := c.Params("*")
	log.Printf("🔍 原始请求路径: %s", c.Path())
	log.Printf("🔍 解析的图片路径: %s", imagePath)
	log.Printf("🔍 完整 URL: %s", c.OriginalURL())
	log.Printf("🔍 数据目录: %s", h.repo.GetDataDir())

	if imagePath == "" {
		log.Printf("❌ 图片路径为空")
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "图片路径不能为空",
		})
	}

	log.Printf("🔍 请求图片: %s", imagePath)

	// 构建完整的文件路径
	fullPath := filepath.Join(h.repo.GetDataDir(), imagePath)
	log.Printf("📁 完整文件路径: %s", fullPath)
	log.Printf("📁 数据目录: %s", h.repo.GetDataDir())
	log.Printf("🔍 检查文件是否存在: %s", fullPath)

	// 检查文件是否存在
	fileInfo, err := os.Stat(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			log.Printf("❌ 文件不存在: %s", fullPath)
		} else if os.IsPermission(err) {
			log.Printf("❌ 权限不足: %s", fullPath)
		} else {
			log.Printf("❌ 文件访问错误: %s, 错误: %v", fullPath, err)
		}
		return c.Status(fiber.StatusNotFound).JSON(models.APIResponse{
			Code: 404,
			Data: "图片文件不存在: " + imagePath,
		})
	}

	log.Printf("✅ 文件存在: %s, 大小: %d bytes", fullPath, fileInfo.Size())

	// 检查文件是否可读
	file, err := os.Open(fullPath)
	if err != nil {
		log.Printf("❌ 无法打开文件: %s, 错误: %v", fullPath, err)
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "无法读取图片文件",
		})
	}
	defer file.Close()

	// 设置正确的 Content-Type
	contentType := "image/jpeg"
	if strings.HasSuffix(imagePath, ".png") {
		contentType = "image/png"
	} else if strings.HasSuffix(imagePath, ".gif") {
		contentType = "image/gif"
	} else if strings.HasSuffix(imagePath, ".webp") {
		contentType = "image/webp"
	}
	c.Set("Content-Type", contentType)

	log.Printf("✅ 准备发送文件: %s, Content-Type: %s", fullPath, contentType)

	// 直接返回文件
	return c.SendFile(fullPath)
}

// GetAudio 获取音频文件
func (h *CardHandler) GetAudio(c *fiber.Ctx) error {
	audioPath := c.Params("*")
	log.Printf("🔍 原始请求路径: %s", c.Path())
	log.Printf("🔍 解析的音频路径: %s", audioPath)
	log.Printf("🔍 完整 URL: %s", c.OriginalURL())
	log.Printf("🔍 数据目录: %s", h.repo.GetDataDir())

	if audioPath == "" {
		log.Printf("❌ 音频路径为空")
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "音频路径不能为空",
		})
	}

	log.Printf("🔍 请求音频: %s", audioPath)

	// 构建完整的文件路径
	fullPath := filepath.Join(h.repo.GetDataDir(), audioPath)
	log.Printf("📁 完整文件路径: %s", fullPath)
	log.Printf("📁 数据目录: %s", h.repo.GetDataDir())
	log.Printf("🔍 检查文件是否存在: %s", fullPath)

	// 检查文件是否存在
	fileInfo, err := os.Stat(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			log.Printf("❌ 文件不存在: %s", fullPath)
		} else if os.IsPermission(err) {
			log.Printf("❌ 权限不足: %s", fullPath)
		} else {
			log.Printf("❌ 文件访问错误: %s, 错误: %v", fullPath, err)
		}
		return c.Status(fiber.StatusNotFound).JSON(models.APIResponse{
			Code: 404,
			Data: "音频文件不存在: " + audioPath,
		})
	}

	log.Printf("✅ 文件存在: %s, 大小: %d bytes", fullPath, fileInfo.Size())

	// 检查文件是否可读
	file, err := os.Open(fullPath)
	if err != nil {
		log.Printf("❌ 无法打开文件: %s, 错误: %v", fullPath, err)
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "无法读取音频文件",
		})
	}
	defer file.Close()

	// 设置正确的 Content-Type
	contentType := "audio/mpeg"
	if strings.HasSuffix(audioPath, ".wav") {
		contentType = "audio/wav"
	} else if strings.HasSuffix(audioPath, ".ogg") {
		contentType = "audio/ogg"
	} else if strings.HasSuffix(audioPath, ".aac") {
		contentType = "audio/aac"
	} else if strings.HasSuffix(audioPath, ".flac") {
		contentType = "audio/flac"
	}
	c.Set("Content-Type", contentType)

	log.Printf("✅ 准备发送文件: %s, Content-Type: %s", fullPath, contentType)

	// 直接返回文件
	return c.SendFile(fullPath)
}

// GetSyncStatus 获取同步状态
func (h *CardHandler) GetSyncStatus(c *fiber.Ctx) error {
	deviceID := c.Query("device_id")
	if deviceID == "" {
		deviceID = "unknown"
	}

	count, err := h.repo.GetCardCount()
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取同步状态失败",
		})
	}

	syncInfo := models.SyncResponse{
		DeviceID:   deviceID,
		SyncTime:   time.Now().Format(time.RFC3339),
		CardsCount: count,
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: syncInfo,
	})
}

// SearchCards 搜索卡片
func (h *CardHandler) SearchCards(c *fiber.Ctx) error {
	title := c.Query("title")
	if title == "" {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "搜索标题不能为空",
		})
	}

	cards, err := h.repo.GetCardsByTitle(title)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "搜索卡片失败",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: cards,
	})
}

// GetCardsByDateRange 根据日期范围获取卡片
func (h *CardHandler) GetCardsByDateRange(c *fiber.Ctx) error {
	startDate := c.Query("start_date")
	endDate := c.Query("end_date")

	if startDate == "" || endDate == "" {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "开始日期和结束日期不能为空",
		})
	}

	cards, err := h.repo.GetCardsByDateRange(startDate, endDate)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取日期范围卡片失败",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: cards,
	})
}

// BatchCreateCards 批量创建卡片
func (h *CardHandler) BatchCreateCards(c *fiber.Ctx) error {
	var cards []*models.Card
	if err := c.BodyParser(&cards); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "请求参数无效",
		})
	}

	if len(cards) == 0 {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "卡片列表不能为空",
		})
	}

	err := h.repo.BatchCreateCards(cards)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "批量创建卡片失败",
		})
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: map[string]interface{}{
			"message": fmt.Sprintf("批量创建 %d 张卡片成功", len(cards)),
			"count":   len(cards),
		},
	})
}

// HealthCheck 健康检查
func (h *CardHandler) HealthCheck(c *fiber.Ctx) error {
	count, err := h.repo.GetCardCount()
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "健康检查失败",
		})
	}

	healthInfo := models.HealthResponse{
		Status:     "ok",
		Service:    "baby-tap-api",
		Platform:   "mobile",
		Time:       time.Now().Format(time.RFC3339),
		CardsCount: count,
	}

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: healthInfo,
	})
}

// SendUDPBroadcast 发送UDP广播
func (h *CardHandler) SendUDPBroadcast(c *fiber.Ctx) error {
	log.Println("📡 收到UDP广播请求")

	// 检查UDP发现服务是否可用
	if h.udpDiscovery == nil {
		log.Println("❌ UDP发现服务未初始化")
		return c.Status(fiber.StatusServiceUnavailable).JSON(models.APIResponse{
			Code: 503,
			Data: "UDP发现服务未初始化",
		})
	}

	// 通过反射调用UDP发现服务的手动广播方法
	udpDiscoveryValue := reflect.ValueOf(h.udpDiscovery)
	if udpDiscoveryValue.IsNil() {
		log.Println("❌ UDP发现服务实例为空")
		return c.Status(fiber.StatusServiceUnavailable).JSON(models.APIResponse{
			Code: 503,
			Data: "UDP发现服务实例为空",
		})
	}

	sendMethod := udpDiscoveryValue.MethodByName("SendManualBroadcast")
	if !sendMethod.IsValid() {
		log.Println("❌ UDP发现服务没有SendManualBroadcast方法")
		return c.Status(fiber.StatusServiceUnavailable).JSON(models.APIResponse{
			Code: 503,
			Data: "UDP发现服务方法不可用",
		})
	}

	// 调用手动广播方法
	results := sendMethod.Call(nil)
	if len(results) > 0 && !results[0].IsNil() {
		err := results[0].Interface().(error)
		log.Printf("❌ 手动UDP广播失败: %v", err)
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: fmt.Sprintf("UDP广播失败: %v", err),
		})
	}

	log.Println("✅ 通过Golang UDP发现服务发送广播成功")

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: map[string]interface{}{
			"message":   "UDP广播发送成功",
			"timestamp": time.Now().Format(time.RFC3339),
		},
	})
}

// GetDeviceName 获取设备名称
func (h *CardHandler) GetDeviceName(c *fiber.Ctx) error {
	if h.udpDiscovery == nil {
		return c.Status(fiber.StatusServiceUnavailable).JSON(models.APIResponse{
			Code: 503,
			Data: "UDP发现服务未初始化",
		})
	}

	udpDiscoveryValue := reflect.ValueOf(h.udpDiscovery)
	getMethod := udpDiscoveryValue.MethodByName("GetDeviceName")
	if !getMethod.IsValid() {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取设备名称方法不存在",
		})
	}

	results := getMethod.Call(nil)
	if len(results) == 0 {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "获取设备名称失败",
		})
	}

	deviceName := results[0].String()
	return c.JSON(models.APIResponse{
		Code: 0,
		Data: map[string]interface{}{
			"name": deviceName,
		},
	})
}

// SetDeviceName 设置设备名称
func (h *CardHandler) SetDeviceName(c *fiber.Ctx) error {
	if h.udpDiscovery == nil {
		return c.Status(fiber.StatusServiceUnavailable).JSON(models.APIResponse{
			Code: 503,
			Data: "UDP发现服务未初始化",
		})
	}

	var request struct {
		Name string `json:"name"`
	}

	if err := c.BodyParser(&request); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "无效的请求格式",
		})
	}

	if request.Name == "" {
		return c.Status(fiber.StatusBadRequest).JSON(models.APIResponse{
			Code: 400,
			Data: "设备名称不能为空",
		})
	}

	udpDiscoveryValue := reflect.ValueOf(h.udpDiscovery)
	setMethod := udpDiscoveryValue.MethodByName("SetDeviceName")
	if !setMethod.IsValid() {
		return c.Status(fiber.StatusInternalServerError).JSON(models.APIResponse{
			Code: 500,
			Data: "设置设备名称方法不存在",
		})
	}

	setMethod.Call([]reflect.Value{reflect.ValueOf(request.Name)})

	return c.JSON(models.APIResponse{
		Code: 0,
		Data: map[string]interface{}{
			"message": "设备名称设置成功",
			"name":    request.Name,
		},
	})
}
